Promień konturu?

473

Czy mimo uzyskania zaokrąglone narożniki na zarysie Of A div element, podobnie jak border-radius?

Marc Guerin
źródło
2
Cóż, mam pudełko Div z 2-krotną szarą ramką z promieniem 20-krotnym, wędrowałem, czy mogę mieć 10-krotny Outine wokół tej granicy, która jest za granicą, a nie kwadratową
Marc Guerin
4
To dobre pytanie. Element z border: 5px redi outline: 5px bluea border-radius: 5pxgranica jest zaokrąglona, ale zarys jest kwadratowy.
Matthew Rudy,
4
Do tej pory możemy go używać tylko w przeglądarce Firefox:-moz-outline-radius
Wojciech Bednarski
Powinien być częścią CSS3 ... Jeśli się nad tym zastanowić - nienawidzę W3C: D
m93a
17
wszyscy potrzebujecie box-shadoww swoim życiu ..
Muhammad Umer

Odpowiedzi:

538

Stare pytanie teraz, ale może mieć znaczenie dla kogoś z podobnym problemem. Miałem pole wejściowe z zaokrągleniem borderi chciałem zmienić kolor konturu ogniska. Nie mogłem oswoić okropnego kwadratu outlinez kontrolą wejścia.

Zamiast tego użyłem cienia. Właściwie wolałem gładki wygląd cienia, ale cień można stwardnieć, aby symulować zaokrąglony kontur:

 /* Smooth outline with box-shadow: */
    .text1:focus {
        box-shadow: 0 0 3pt 2pt red;
    }

    /* Hard "outline" with box-shadow: */
    .text2:focus {
        box-shadow: 0 0 0 2pt red;
    }
<input type=text class="text1"> 
<br>
<br>
<br>
<br>
<input type=text class="text2">

Lea Hayes
źródło
24
IMO, to jest odpowiedź, której szukasz. Zrobiłem tę metodę, ale nie zapomnij zmienić twojego konturu na 0.
John Morton
2
Właśnie tego szukałem i pasuje nawet lepiej niż promień konturu.
Zenexer
2
Przykładowy zarys nie działa. To tylko prostokąt bez promienia narożnika.
Erik Aigner,
1
outline: 0przerywa dostępność sieci; czytaj outlinenone.com
ianstarz
4
@ianstarz, łamie dostępność, gdy nie zapewnisz alternatywnego stylu. box-shadowjest alternatywną stylizacją (która, jak tu przedstawiono, jest bardzo podobna do wyglądu jak outline).
ACJ
84

Zwykle osiągam to za pomocą pseudoelementu: after:

oczywiście zależy to od użycia, ta metoda pozwala kontrolować poszczególne granice, zamiast używać metody twardego cienia.

możesz również ustawić przesunięcia -1px i ponownie użyć liniowego gradientu tła (bez ramki), aby uzyskać inny efekt.

body {
  margin: 20px;
}

a {
  background: #999;
  padding: 10px 20px;
  border-radius: 5px;
  text-decoration: none;
  color: #fff;
  position: relative;
  border: 2px solid #000;
}

a:after {
  content: '';
  display: block;
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  border-radius: 5px;
  border: 2px solid #ccc;
}
<a href="#">Button</a>

mononim
źródło
3
Zmodyfikowana i nieco bardziej spektakularna wersja: jsfiddle.net/rh6j3cdm .
Dávid Horváth,
2
Nie można utworzyć pseudo :: after dla pola wejściowego
Simon Franzen
dzięki, działało to BARDZO dobrze z konturami zapytań drzewa reagującego na sortowanie!
Monarch Wadia,
Podoba mi się to rozwiązanie, ponieważ jest znacznie bardziej elastyczne niż box-shadowwersja. Na przykład, jeśli chcesz, aby „kontur” był oddalony od elementu (tj. Symulując outline-offset), staje się to możliwe dzięki tej technice.
Kirk Woll
34

Podobnie jak powyżej Lea Hayes, ale oto jak to zrobiłem:

div {
  background: #999;
  height: 100px;
  width: 200px;
  border: #999 solid 1px;
  border-radius: 10px;
  margin: 15px;
  box-shadow: 0px 0px 0px 1px #fff inset;
}
<div></div>

Nie jest konieczne zagnieżdżanie DIV ani jQuery, ale dla zwięzłości pominąłem warianty -moz i -webkit niektórych CSS. Możesz zobaczyć wynik powyżej

Heraldmonkey
źródło
6
Mówi o konspekcie, a nie o granicy… promień „konturu”
android.nick
5
poprawne, ale ponieważ promień konturu nie jest dostępny, moja metoda nadaje wygląd ramki i konturu. Jest to efekt wizualny, więc jeśli projekt Marca nie jest określony z dokładnością do piksela, fakt, że tak naprawdę nie używa właściwości konturu, nie ma znaczenia. A ponieważ jest to praktyczne rozwiązanie, doceniłbym głosowanie z powrotem
Heraldmonkey
2
To działało świetnie. Nie skorzystałem insetjednak i dostałem to, czego chciałem.
Paul Schreiber
18

Chciałem uzyskać dobry dostęp do fokusu menu rozwijanych na pasku nawigacyjnym Bootstrap i byłem z tego zadowolony:

     a.dropdown-toggle:focus {
         display: inline-block;
         box-shadow: 0 0 0 2px #88b8ff;
         border-radius: 2px;
     }
<a href="https://stackoverflow.com" class="dropdown-toggle">Visit Stackoverflow</a>

StackOverflowUser
źródło
16

Chyba szukasz czegoś takiego .

div {
    -webkit-border-radius: 10px;
    -moz-border-radius: 10px;
    border-radius: 10px;
    border: 1px solid black;
    background-color: #CCC;
    height: 100px;
    width: 160px;
}

Edytować

Istnieje tylko Firefox -moz-outline-radius, ale to nie działa w IE / Chrome / Safari / Opera / etc. Tak więc wygląda na to, że najbardziej kompatybilnym z różnymi przeglądarkami sposobem * uzyskania zakrzywionej linii wokół granicy jest użycie otoki otoki:

div.inner {
  -webkit-border-radius: 10px;
  -moz-border-radius: 10px;
  border-radius: 10px;
  border: 1px solid black;
  background-color: #CCC;
  height: 100px;
  width: 160px;
}

div.outer {
  display: inline-block;
  -webkit-border-radius: 10px;
  -moz-border-radius: 10px;
  border-radius: 10px;
  border: 1px solid red;
}
<div class="outer">
  <div class="inner"></div>
</div>


* oprócz korzystania z obrazów

Matt Ball
źródło
20
Nie, wiem, jak uzyskać Promień Graniczny, na który wędrowałem, jeśli można uzyskać Promień Zarysu
Marc Guerin
Co dokładnie znaczy? Grubszy zarys, jak ten? jsfiddle.net/mattball/NXZFv/1
Matt Ball
10
@Matt: oczywiście zakrzywiony kontur zamiast obramowania . Zobacz w3.org/TR/CSS21/ui.html#dynamic-outlines
Joey
Cóż, mam pudełko Div z 2-krotną szarą ramką z promieniem 20-krotności, wędrowałem, czy mogę mieć 10-krotny Outine wokół tej granicy, która jest wzdłuż granicy, a nie kwadrat.
Marc Guerin
1
Tylko jeden dodatek do kodu matowego, jeśli upuścisz promień obramowania o kilka pikseli na wewnętrznym polu, róg staje się znacznie ciaśniejszy, dzięki za pomoc
Marc Guerin
7

Właśnie znalazłem świetne rozwiązanie tego problemu i po zapoznaniu się z wszystkimi dotychczasowymi odpowiedziami nie widziałem jeszcze tego opublikowanego. Oto co zrobiłem:

Utworzyłem regułę CSS dla klasy i użyłem pseudoklasy: focus dla tej reguły. Postanowiłem outline: nonepozbyć się tego domyślnego jasnoniebieskiego „konturu”, który nie obsługuje granic, którego domyślnie używa Chrome. Następnie w tej samej :focuspseudoklasie, gdzie ten kontur już nie istnieje, dodałem właściwości promienia i obramowania. Prowadząc do następujących

outline: none;
border-radius: 5px;
border: 2px solid maroon;

aby mieć bordowy kontur z promieniem obramowania, który teraz pojawia się, gdy element zostanie zaznaczony tabulatorem przez użytkownika.

Branden Pinney
źródło
Używanie „konspektu: 0” lub „konspektu: brak” jest uważane za złą praktykę i niszczy dostęp użytkowników. W tym momencie nie mam poprawki, ale oto artykuł o tym, dlaczego nie należy usuwać konturu, jeśli to możliwe, i co zrobić, jeśli absolutnie musisz. Nigdy nie usuwaj konturów CSS
AndrewBrntt
5

Jeśli chcesz uzyskać wytłoczony wygląd, możesz wykonać następujące czynności:

.embossed {
  background: #e5e5e5;
  height: 100px;
  width: 200px;
  border: #FFFFFF solid 1px;
  outline: #d0d0d0 solid 1px;
  margin: 15px;
}

.border-radius {
  border-radius: 20px 20px 20px 20px;
  -webkit-border-radius: 20px;
  -moz-border-radius: 20px;
  -khtml-border-radius: 20px;
}

.outline-radius {
  -moz-outline-radius: 21px;
}
<div class="embossed"></div>
<div class="embossed border-radius"></div>
<div class="embossed border-radius outline-radius">-MOZ ONLY</div>

Nie znalazłem rozwiązania, aby mieć tę pracę w innych przeglądarkach.

EDYCJA: Jedynym innym sposobem, w jaki możesz to zrobić, jest użycie ramki-cienia, ale to nie zadziała, jeśli masz już cień ramki dla tego elementu.

James Kyle
źródło
1
Możesz użyć wielu cieni w tym samym elemencie, oddzielając je przecinkami.
Bangash,
2

Jest rozwiązanie, jeśli potrzebujesz tylko kontur bez obramowania. To nie moje. Mam jeśli z pliku css Bootstrap. Jeśli określisz outline: 1px auto certain_color, otrzymasz cienką linię zewnętrzną wokół div określonego koloru. W takim przypadku podana szerokość nie ma znaczenia, nawet jeśli określisz szerokość 10 pikseli, i tak będzie to cienka linia. Kluczowym słowem wspomnianej reguły jest „auto”.
Jeśli potrzebujesz konturu z zaokrąglonymi narożnikami i określoną szerokością, możesz dodać regułę css na granicy o wymaganej szerokości i tym samym kolorze. Zwiększa grubość konturu.

Aleks Sid
źródło
2

O ile mi wiadomo, Outline radiusjest obsługiwany tylko przez Firefox i Firefox dla Androida.

-moz-outline-radius: 1em;

wprowadź opis zdjęcia tutaj

ucMedia
źródło
1

Nie. Granice znajdują się na zewnątrz elementu i po wewnętrznej stronie marginesu modelu pudełkowego. Kontury znajdują się po wewnętrznej stronie elementu, a obszar wypełnienia modelu pudełkowego go ignoruje. Nie jest przeznaczony do estetyki. Wystarczy pokazać konstruktorowi zarysy elementów. Na przykład na wczesnych etapach opracowywania dokumentu HTML, deweloper może potrzebować szybkiego rozpoznania, czy umieścił wszystkie elementy szkieletu we właściwym miejscu. Później może być konieczne sprawdzenie, czy różne przyciski i formularze mają poprawną liczbę pikseli od siebie.

Granice mają charakter estetyczny. W przeciwieństwie do konturów, faktycznie są one oddzielne od modelu pudełkowego, co oznacza, że ​​nie nakładają się na tekst ustawiony na margines: 0; a każdą stronę granicy można stylizować indywidualnie.

Jeśli próbujesz zastosować promień narożnika do konturu, zakładam, że używasz go tak, jak większość ludzi używa obramowania. Więc jeśli nie masz nic przeciwko, żebym zapytał, jaka właściwość konturu sprawia, że ​​jest pożądana ponad granicami?

Musixauce3000
źródło
10
Celem konturów jest nawigacja / dostępność klawiatury, a nie pokazywanie programistom, gdzie są elementy
danwellman
Do tego domyślnie używają ich przeglądarki. Ale zawsze używałem ich, aby zobaczyć, gdzie są moje divy, z wielkim skutkiem.
Musixauce3000
+1 za wzmiankę, że „Granice znajdują się na zewnątrz elementu i wewnątrz obszaru marginesu modelu pudełkowego. Kontury znajdują się po wewnętrznej stronie elementu, a obszar wypełnienia modelu pudełkowego go ignoruje”.
Jacques
1

POŁĄCZENIE CIENIA I ZARYSU.

Znalazłem delikatny zwrot w odpowiedzi Lei Hayes

input[type=text]:focus {
    box-shadow: 0 0 0 1pt red;
    outline-width: 1px;
    outline-color: red;
}

dostaje naprawdę ładne, czyste wykończenie. Brak skoku, jaki uzyskujesz, gdy używasz promienia granicy

fidev
źródło
1

Jak powiedzieli inni, obsługuje to tylko Firefox. Oto obejście, które robi to samo, a nawet działa z przerywanymi konturami.

przykład

.has-outline {
    display: inline-block;
    background: #51ab9f;
    border-radius: 10px;
    padding: 5px;
    position: relative;
}
.has-outline:after {
  border-radius: 10px;
  padding: 5px;
  border: 2px dashed #9dd5cf;
  position: absolute;
  content: '';
  top: -2px;
  left: -2px;
  bottom: -2px;
  right: -2px;
}
<div class="has-outline">
  I can haz outline
</div>

RobKohr
źródło
0

Spróbuj użyć wypełnienia i koloru tła dla obramowania, a następnie obramowania dla konspektu:

.round_outline {
  padding: 8px;
  background-color: white;
  border-radius: 50%;
  border: 1px solid black;
}

W moim przypadku zadziałało.

Eric
źródło
0

Właśnie ustawiłem przezroczysty kontur.

input[type=text] {
  outline: rgba(0, 0, 0, 0);
  border-radius: 10px;
}

input[type=text]:focus {    
  border-color: #0079ff;
}
Ireneml.fr
źródło
0

Lubię to.

.circle:before {
   content: "";
   width: 14px;
   height: 14px;
   border: 3px solid #fff;
   background-color: #ced4da;
   border-radius: 7px;
   display: inline-block;
   margin-bottom: -2px;
   margin-right: 7px;
   box-shadow: 0px 0px 0px 1px #ced4da;
}

Utworzy szary okrąg z obramowaniem dowcipu i ponownie 1 piksel wokół obramowania!

Andris
źródło
0
clip-path: circle(100px at center);

To sprawi, że klikalne będzie tylko koło, podczas gdy promień obramowania nadal tworzy kwadrat, ale wygląda jak koło.

Martin Zvarík
źródło
0

Prosta odpowiedź na podstawowe pytanie brzmi: nie. Jedyną opcją dla różnych przeglądarek jest utworzenie hacka, który osiągnie to, co chcesz. Takie podejście niesie ze sobą pewne potencjalne problemy, jeśli chodzi o stylizację wcześniej istniejących treści , ale zapewnia większą personalizację konturu (przesunięcie, szerokość, styl linii) niż wiele innych rozwiązań.

Na poziomie podstawowym rozważ następujący przykład statyczny (uruchom snippent dla wersji demonstracyjnej):

.outline {
    border: 2px dotted transparent;
    border-radius: 5px;
    display: inline-block;
    padding: 2px;
    margin: -4px;
}

/* :focus-within does not work in Edge or IE */
.outline:focus-within, .outline.edge {
    border-color: blue;
}

br {
    margin-bottom: 0.75rem;
}
<h3>Javascript-Free Demo</h3>
<div class="outline edge"><input type="text" placeholder="I always have an outline"/></div><br><div class="outline"><input type="text" placeholder="I have an outline when focused"/></div> *<i>Doesn't work in Edge or IE</i><br><input type="text" placeholder="I have never have an outline" />
<p>Note that the outline does not increase the spacing between the outlined input and other elements around it. The margin (-4px) compensates for the space that the outlines padding (-2px) and width (2px) take up, a total of 4px.</p>

Teraz, na bardziej zaawansowanym poziomie, możliwe byłoby użycie JavaScript do ładowania elementów danego typu lub klasy, aby były one zawinięte w div, który symuluje kontur przy ładowaniu strony. Ponadto można ustanowić powiązania zdarzeń, aby wyświetlać lub ukrywać zarys interakcji użytkownika w ten sposób (uruchom fragment kodu poniżej lub otwórz w JSFiddle ):

h3 {
  margin: 0;
}

div {
  box-sizing: border-box;
}

.flex {
  display: flex;
}

.clickable {
  cursor: pointer;
}

.box {
  background: red;
  border: 1px solid black;
  border-radius: 10px;
  height: 5rem;
  display: flex;
  align-items: center;
  text-align: center;
  color: white;
  font-weight: bold;
  padding: 0.5rem;
  margin: 1rem;
}
<h3>Javascript-Enabled Demo</h3>
<div class="flex">
  <div class="box outline-me">I'm outlined because I contain<br>the "outline-me" class</div>
  <div class="box clickable">Click me to toggle outline</div>
</div>
<hr>
<input type="text" placeholder="I'm outlined when focused" />

<script>
// Called on an element to wrap with an outline and passed a styleObject
// the styleObject can contain the following outline properties:
// 		style, width, color, offset, radius, bottomLeftRadius,
//		bottomRightRadius, topLeftRadius, topRightRadius
// It then creates a new div with the properties specified and 
// moves the calling element into the div
// The newly created wrapper div receives the class "simulated-outline"
Element.prototype.addOutline = function (styleObject, hideOutline = true) {
    var element = this;

    // create a div for simulating an outline
    var outline = document.createElement('div');

    // initialize css formatting
    var css = 'display:inline-block;';

    // transfer any element margin to the outline div
    var margins = ['marginTop', 'marginBottom', 'marginLeft', 'marginRight'];
    var marginPropertyNames = { 
        marginTop: 'margin-top',
        marginBottom: 'margin-bottom',
        marginLeft: 'margin-left',
        marginRight: 'margin-right'
    }
    var outlineWidth = Number.parseInt(styleObject.width);
    var outlineOffset = Number.parseInt(styleObject.offset);
    for (var i = 0; i < margins.length; ++i) {
        var computedMargin = Number.parseInt(getComputedStyle(element)[margins[i]]);
        var margin = computedMargin - outlineWidth - outlineOffset;
        css += marginPropertyNames[margins[i]] + ":" + margin + "px;";
    }
    element.style.cssText += 'margin:0px !important;';
    
    // compute css border style for the outline div
    var keys = Object.keys(styleObject);
    for (var i = 0; i < keys.length; ++i) {
        var key = keys[i];
        var value = styleObject[key];
        switch (key) {
            case 'style':
                var property = 'border-style';
                break;
            case 'width':
                var property = 'border-width';
                break;
            case 'color':
                var property = 'border-color';
                break;
            case 'offset':
                var property = 'padding';
                break;
            case 'radius':
                var property = 'border-radius';
                break;
            case 'bottomLeftRadius':
                var property = 'border-bottom-left-radius';
                break;
            case 'bottomRightRadius':
                var property = 'border-bottom-right-radius';
                break;
            case 'topLeftRadius':
                var property = 'border-top-left-radius-style';
                break;
            case 'topRightRadius':
                var property = 'border-top-right-radius';
                break;
        }
        css += property + ":" + value + ';';
    }
    
    // apply the computed css to the outline div
    outline.style.cssText = css;
    
    // add a class in case we want to do something with elements
    // receiving a simulated outline
    outline.classList.add('simulated-outline');
    
    // place the element inside the outline div
    var parent = element.parentElement;
    parent.insertBefore(outline, element);
    outline.appendChild(element);

    // determine whether outline should be hidden by default or not
    if (hideOutline) element.hideOutline();
}

Element.prototype.showOutline = function () {
    var element = this;
    // get a reference to the outline element that wraps this element
    var outline = element.getOutline();
    // show the outline if one exists
    if (outline) outline.classList.remove('hide-outline');
}


Element.prototype.hideOutline = function () {
    var element = this;
    // get a reference to the outline element that wraps this element
    var outline = element.getOutline();
    // hide the outline if one exists
    if (outline) outline.classList.add('hide-outline');
}

// Determines if this element has an outline. If it does, it returns the outline
// element. If it doesn't have one, return null.
Element.prototype.getOutline = function() {
    var element = this;
    var parent = element.parentElement;
    return (parent.classList.contains('simulated-outline')) ? parent : null;
}

// Determines the visiblity status of the outline, returning true if the outline is
// visible and false if it is not. If the element has no outline, null is returned.
Element.prototype.outlineStatus = function() {
    var element = this;
    var outline = element.getOutline();
    if (outline === null) {
        return null;
    } else {
        return !outline.classList.contains('hide-outline');
    }
}

// this embeds a style element in the document head for handling outline visibility
var embeddedStyle = document.querySelector('#outline-styles');
if (!embeddedStyle) {
    var style = document.createElement('style');
    style.innerText = `
        .simulated-outline.hide-outline {
            border-color: transparent !important;
        }
    `;
    document.head.append(style);
}


/*########################## example usage ##########################*/

// add outline to all elements with "outline-me" class
var outlineMeStyle = {
    style: 'dashed',
    width: '3px',
    color: 'blue',
    offset: '2px',
    radius: '5px'
};
document.querySelectorAll('.outline-me').forEach((element)=>{
  element.addOutline(outlineMeStyle, false);
});


// make clickable divs get outlines
var outlineStyle = {
    style: 'double',
    width: '4px',
    offset: '3px',
    color: 'red',
    radius: '10px'
};
document.querySelectorAll('.clickable').forEach((element)=>{
    element.addOutline(outlineStyle);
    element.addEventListener('click', (evt)=>{
        var element = evt.target;
        (element.outlineStatus()) ? element.hideOutline() : element.showOutline();
    });
});


// configure inputs to only have outline on focus
document.querySelectorAll('input').forEach((input)=>{
    var outlineStyle = {
        width: '2px',
        offset: '2px',
        color: 'black',
        style: 'dotted',
        radius: '10px'
    }
    input.addOutline(outlineStyle);
    input.addEventListener('focus', (evt)=>{
        var input = evt.target;
        input.showOutline();
    });
    input.addEventListener('blur', (evt)=>{
        var input = evt.target;
        input.hideOutline();
    });
});
</script>

Na zakończenie chciałbym powtórzyć, że wdrożenie tego podejścia może wymagać więcej stylizacji niż to, co zawarłem w moich demach, szczególnie jeśli stylizowałeś już element, który chcesz przedstawić.

b_laoshi
źródło