I googled a bit, but maybe someone here can explain it to me why do pseudo elements, namely :before and :after, behave this way.
I have a content div, and inside it there are some elements - paragraphs, anchors, icon, etc. Let's say that on one anchor element I added an :after pseudo element and filled it with a content that will show an icon
a:after{
content:"\f001";
font-family: "Awesome icon font";
display: inline-block;
}
I can toggle the visibility of that element with a click on a button.
The issue is that when that element is hidden, no pseudo element is shown in the DOM. Once I toggle it's visibility (from display:none; to, let's say display: inline-block;) the pseudo element will be shown.
In a more concrete example I have a nav menu, that can be hidden or shown if I click on a 'hamburger' menu. One nav item is a shopping cart icon. I'm toggling the slide up animation with the click on the menu icon. All the textual menus will slide up nicely, but only when the animation is finished will the shop icon 'pop' into existence. Which looks kinda sloppy.
Why is this happening? Why is the display value, on the container in which the pseudo elements are nested in, controlling the display of the pseudo elements (even though they themselves have a display value that is different from none)? Not only does it affect their display value, when you inspect the DOM, if the container has display: none; value, there won't be any pseudo element present.
EDIT:
Example fiddle : http://jsfiddle.net/at4u56fy/
Lets see what documentation says...
About display: none;
This value causes an element to not appear in the formatting structure
(i.e., in visual media the element generates no boxes and has no
effect on layout). Descendant elements do not generate any boxes
either; the element and its content are removed from the formatting
structure entirely. This behavior cannot be overridden by setting the
'display' property on the descendants.
Please note that a display of 'none' does not create an invisible box;
it creates no box at all. CSS includes mechanisms that enable an
element to generate boxes in the formatting structure that affect
formatting but are not visible themselves. Please consult the section
on visibility for details.
Going further to formatting structure it says :
From the annotated document tree, generate a formatting structure.
Often, the formatting structure closely resembles the document tree,
but it may also differ significantly, notably when authors make use of
pseudo-elements and generated content. First, the formatting structure
need not be "tree-shaped" at all -- the nature of the structure
depends on the implementation. Second, the formatting structure may
contain more or less information than the document tree. For instance,
if an element in the document tree has a value of 'none' for the
'display' property, that element will generate nothing in the
formatting structure. A list element, on the other hand, may generate
more information in the formatting structure: the list element's
content and list style information (e.g., a bullet image).
Note that the CSS user agent does not alter the document tree during
this phase. In particular, content generated due to style sheets is
not fed back to the document language processor (e.g., for reparsing).
So its like if the element is set to display: none; user agents seem to ignore CSS generated content. Hence you might want to take a look at visibility: hidden; which should work for you.
Related
Doing work to ensure my site if accessible and one of the requirements is the text spacing criterion should be applied when a user invokes a text spacing bookmarklet. I've realized the issue is when a bookmarklet is triggered on the site it automatically changes the styling for the text elements to match the requirements but is not applied to items in the combo box because I've used select and input tags which according to this post style attributes cannot be applied to input elements so the changes are not applied to the items in the combo box.
How can I ensure the text spacing can also be applied to elements in the combo box when a bookmarklet is invoked? Thanks
It's admirable to try to implement this but WCAG 1.4.12 is not requiring you to do this. That success criterion says that if the user applies those styles, then there should be "no loss of content or functionality". It does not say that if the user applies those styles that those styles must be applied to every element on the page. It's really the browser's responsibility to apply styles to elements.
If the user has a custom style sheet applied to the webpage and, for example, has
* { letter-spacing: 0.12em !important; }
then if that letter spacing is not applied to the <select>/<option> element, it's the browser's problem.
As long as your page looks good with that style applied (meaning there's "no loss of content or functionality"), then you're ok.
Was able to achieve this by using the angular alternative components and which achieves the same implementation and are more accessible
Other display values have one or more corresponding HTML elements, such as:
block - div, p
inline - span, strong, etc.
list-item - li
table - table, table-row - tr, etc.
none - template
but display: grid and display: flex must be assigned through styling. I could see it being easier to read through the DOM if <flex> and <grid> elements were available.
Are new element types not being added to the spec now that custom elements can be made?
The answer to your question has to do with the separation of style from the data being presented.
The HTML tags that you use to display data should be chosen based on the type of data that you are displaying. For example, you'd use <li> when you're producing a list or <strong> when you want text to stand out. CSS gives you a lot of flexibility for modifying how the data is presented allowing you can change how data, such as text in <strong> or <em> tags, is displayed. The styles for many tags can be changed so that they behave like other tags. For example, you can make a <span> tag behave like a <div> tag and vice versa. However, you should not do this. In other words, the tags that you select should be based on the type of data being displayed, such as <li> for list items or <p> for paragraphs. Technically, you can never completely separate your data from how it is displayed, but you should attempt to do so as much as is possible.
<flex> and <grid> don't have any meaning with respect to the type of data that you want to display. Thus, they are styles that are editable using CSS (instead of tags).
I could see it being easier to read through the DOM if <flex> and <grid> elements were available.
You're suggesting combining content and presentation, which counters the separation of concerns principle that CSS was created to address.
HTML is used for organization of content. CSS is used for presentation of content. Your <flex> and <grid> elements would combine these two concerns, which is the way things were in the 1990s, before the advent of CSS, when HTML did both.
Also, what if I want my <article> to be a grid container, or my <aside> to be a flex container?
Why not also have <block> and <inline>?
Things start getting messy.
Also, the premise of your question is incorrect.
Other display values have one or more corresponding HTML elements ... but display: grid and display: flex must be assigned through styling.
Actually, the display value of all HTML elements is assigned. The only difference is where the styling comes from.
In raw form, HTML elements have no styles. They only have semantic meaning.
It isn't until the browser assigns default styles that elements take on presentational meaning.
Therefore, the only reason you can say this...
Other display values have one or more corresponding HTML elements,
such as:
block - div, p
inline - span, strong, etc.
list-item - li
table - table, table-row - tr, etc.
... is because the browser defined those elements as such with something like this:
Appendix D. Default style sheet for HTML 4
As you can see, display values are assigned.
So the browser sets a basic level of formatting for HTML elements. Changes and additions to these styles are left up to authors.
Here's some more detail:
Proper way to apply CSS to HTML5 custom elements
<main> element not working in Internet Explorer 11
Just like removeAttribute in JavaScript, after which the element won't be visible in the source.
You cannot remove an element from the DOM tree using CSS. You can only prevent it from being rendered in the layout with display: none; doing so does not prevent it from responding to events or cause it to be ignored by CSS selectors such as + and :nth-child(). You won't be able to interact with an element that's not there so you wouldn't be able to trigger events the usual way, but its "essence" remains, so to speak.
Its not possible with CSS.
Even if you use display:none, the element will be still in DOM tree.
CSS is for styling not for DOM manipulation. Use JavaScript for that.
display: none;
'Unlike the visibility property, which leaves an element in normal document flow,display: none removes the element completely from the document. It does not take up any space, even though the HTML for it is still in the source code. This is because it is, indeed, removed from the document flow. For all intents and purposes, the item is gone. This can be a good thing or a bad thing, depending on what your intentions are. It can also be damaging to your page if you misuse this property!'
https://www.lifewire.com/display-none-vs-visibility-hidden-3466884
You can use display: none to hide an element but it will still be on the DOM.
You can also use visibility: hidden and it will also still be on the DOM but the DOM will reflect the same vertical flow even though the element is hidden. In other words if the element is a block, a block space will still be reserved for the hidden element. And with display: none the space will also be removed along with the element as it is hidden.
Unless you use JavaScript, with CSS you are only changing the visibility of a DOM element that is existent on the DOM. Which can absolutely serve your purpose depending on what you are trying to do.
If you need more help, just comment with more detail and I'd be glad to help.
You actually can. Not directly in CSS but in combination with Javascript/jQuery you could.
In HTML give a class of "removeFromDom" to the Elements you want to have removed.
<p class="removeFromDom">your text here</p>
In CSS you add these Lines to make it invisible, if JS is not working.
.removeFromDom { display:none !important; visibility:hidden !important; }
In a jQuery file, that you load on any site, create this function::
$(document).ready(function() {
$(".removeFromDom").remove();
});
Et voila.. your jQuery file removes your Items from the DOM. I wouldn't recommend it for security reasons if there is a link nobody should be able to see anytime..
I've grid with several boxes in (<div>). Each box has inside a list with couple/ several links (simple ul li list with <a> elements). This link list is hidden, it shows only on hover.
It works really fine, but I have accessibility issue, namely, I can't get into any list element with "tab" key (box <div> works ok, it get focus, so the list is showing up), it is just skipping to next box element. I've tried with adding tabindex on each box and each list element inside, but it seems that this is not the solution.
Is there any CSS/ HTML solution for that? I can of course write simple JS, that will check where is focus and if focus has parent with focus option, but I would like to avoid it if possible.
How did you hide the link list? Using display: none or using visibility: hidden. (And that you apply this only to the list elements or also to the div? From your description, I guess it applies only to the list elements.) Content that is hidden using display: none is not keyboard accessible.
In order to make the list appear on hover, are you using a JavaScript event handler or CSS? If you are using JavaScript, you probably need to add an event listener that responds to keyboard events (e.g. onfocus, but as mentioned above, content hidden with display: none won't receive focus). In CSS, I always recommend adding the :focus pseudo-class whenever :hover is used (unless you want different styles for these things).
You may need to write some JavaScript that toggles the visibility of the lists when a parent div receives focus. (If you have tabindex on the div elements, as you say, they should already be able to receive focus.)
I'm writing a simple contenteditable-based HTML editor, one which lets the user edit a page that is styled by their own CSS (which they can live-edit) and also do basic things like insert new tags, apply classes, etc.
One feature I'd like to have is an option to toggle the display of dotted borders around divs, much like you typically find in WYSIWYG HTML editors such as Dreamweaver, Expression Web, and many others. (This helps the user see her divs even when they have no visible border.)
Is there any possible way to do this? Some ideas:
I can't simply modify the CSS on the actual/existing divs, since they may already have their own borders defined, which I should not obliterate with dots. Ideally, I can show a border around the existing borders, which is how things appear in the aforementioned commercial editors. Even if I fall back to actually setting borders on elements that have no existing borders, figuring out which ones have no borders may be difficult, esp. in the face of things like :hover which dynamically change the computed style.
I may wrap these divs inside new divs, which in turn have the dotted border. The tricky part is handling their CSS, e.g.:
Wrappers must be similarly styled as their children, e.g. a div that has width:50px must have a wrapper that's also width:50px (roughly), so I'd either need to continually poll (as there's no way to be notified of indirect style changes, e.g. on the class) for changes to the computed style (which is completely non-scalable), or implement my own CSS engine that runs and determines what has changed each time the user live-edits their CSS.
Polluting the DOM with my own divs is invasive and interferes with rules such as:
/* these may or may not be divs */
.a > .b > .c { ... }
or:
/* if this is wrapped, then they'll all be :first-child */
.foo:first-child { ... }
or perhaps:
/* immediate children of my wrappers would inherit the dotted borders */
.foo { border: inherit; }
Perhaps there's a way to automatically rewrite these rules robustly - to take the last example:
:not(.my-dotted-border) > .foo { border: inherit; }
But even if theoretically possible, there are a ton of cases to worry about and it would be quite hairy.
Lastly, perhaps there's a way to collapse margins even with the dotted border, but I don't know of it.
Another idea is to overlay the borders on top (absolutely positioned with JS based on the dimensions/offsets of the underlying elements), but this is ugly with overlapping elements that have particular z-indexes, and again I'd need to monitor all elements for style changes. Except now it's not enough just to monitor the changes in the explicitly specified styles, as I need to react to changes even to offset and dimensions (e.g. if the user types some text, it may push down all the elements below it, so I must react to that by updating the overlays).
A related question is See the page outlines but this is from the perspective of a user who wants to see outlines - I'm asking from the perspective of a web-based editor implementation, how to provide these outlines.
Thanks in advance for any tips.
You can use the outline and outline-offset CSS properties to style the outline of your editable divs as they will not overwrite any existing borders (they will however overwrite any existing outlines if there are any).
Check out this example to get an idea of how you can implement it: http://jsfiddle.net/EFJ6B/